package storage

import (
	"net"
	"strconv"
	"time"
)

// Kind 缓存数据类型枚举值, 用于标识存储数据的具体类型信息
//   - Redis 存储时自动将每一个 Key 对应的 Type 存储到 Zset 有序集合
//   - Zset 以 Key 为 Member 唯一元素, 其 Score 分数为过期时间戳*100 + Type(最后2位表示 Kind 类型)
//   - 注意:  Kind 最大值为 99, 预留部分枚举值用于扩展使用

type Kind uint8

const (
	KindInvalid Kind = iota // 无效类型

	KindNil        // Nil 空值，不存储数据
	KindSerializer // 其他类型，序列化存储
	KindString
	KindBool

	KindInt64
	KindInt32
	KindInt16
	KindInt8
	KindInt

	KindUint64
	KindUint32
	KindUint16
	KindUint8
	KindUint

	KindFloat64
	KindFloat32

	KindComplex128
	KindComplex64

	KindTime
	KindDuration
	KindWeekday
	KindMonth

	KindBytes
	KindIP

	KindSetString // 字符串集合类型 Memory 结构为 map[string]struct{}, Redis 存储为 Set
	KindSetInt    // 整型集合类型 Memory 结构为 map[int64]struct{}, Redis 存储为 Set
)

var kindValIndex map[string]Kind

func init() {
	// 初始化映射表，便于快速查找对应的类型枚举值
	// last KindSInteger = 26
	kindValIndex = make(map[string]Kind, 26+1)
	for i := range 27 {
		kindValIndex[strconv.Itoa(i)] = Kind(i)
	}
}

func (t Kind) IsValid() bool {
	return t > 0 && t <= KindSetInt
}
func (t Kind) String() string {
	switch t {
	case KindNil:
		return "<nil>"
	case KindString:
		return "string"
	case KindBool:
		return "bool"
	case KindInt64:
		return "int64"
	case KindInt32:
		return "int32"
	case KindInt16:
		return "int16"
	case KindInt8:
		return "int8"
	case KindInt:
		return "int"
	case KindUint64:
		return "uint64"
	case KindUint32:
		return "uint32"
	case KindUint16:
		return "uint16"
	case KindUint8:
		return "uint8"
	case KindUint:
		return "uint"
	case KindFloat64:
		return "float64"
	case KindFloat32:
		return "float32"
	case KindTime:
		return "time.Time"
	case KindDuration:
		return "time.Duration"
	case KindWeekday:
		return "time.Weekday"
	case KindMonth:
		return "time.Month"
	case KindComplex128:
		return "complex128"
	case KindComplex64:
		return "complex64"
	case KindIP:
		return "net.IP"
	case KindBytes:
		return "bytes"
	case KindSetString:
		return "set<string>" // 字符串集合类型
	case KindSetInt:
		return "set<int64>" // 整型集合类型
	case KindSerializer:
		return "<serializer>"
	default:
		return "<invalid>"
	}
}
func KindParse(str string) Kind {
	if kind, ok := kindValIndex[str]; ok {
		return kind
	}
	switch str {
	case "<invalid>":
		return KindNil
	case "<nil>":
		return KindNil
	case "string":
		return KindString
	case "bool":
		return KindBool
	case "int64":
		return KindInt64
	case "int32":
		return KindInt32
	case "int16":
		return KindInt16
	case "int8":
		return KindInt8
	case "int":
		return KindInt
	case "uint64":
		return KindUint64
	case "uint32":
		return KindUint32
	case "uint16":
		return KindUint16
	case "uint8":
		return KindUint8
	case "uint":
		return KindUint
	case "float64":
		return KindFloat64
	case "float32":
		return KindFloat32
	case "complex128":
		return KindComplex128
	case "complex64":
		return KindComplex64
	case "time.Time":
		return KindTime
	case "time.Duration":
		return KindDuration
	case "time.Weekday":
		return KindWeekday
	case "time.Month":
		return KindMonth
	case "bytes":
		return KindBytes
	case "net.IP":
		return KindIP
	case "map[string]struct{}", "set<string>":
		return KindSetString
	case "map[int64]struct{}", "set<int64>":
		return KindSetInt
	case "<serializer>":
		return KindSerializer
	default:
		return KindInvalid
	}
}

// KindDetect 获取指定val值的类型，主要用于缓存存储时判断数据类型
//   - val 为 underefVal 已预处理过指针脱敏后的基本标量类型
//   - val 为 nil 时，返回 KindNil
//   - 注意: KindSetString / KindSetInt 这两种类型由驱动层直接设置，此处不处理
func KindDetect(val any) Kind {
	if val == nil {
		return KindNil
	}
	switch val.(type) {
	case string:
		return KindString
	case bool:
		return KindBool
	case int64:
		return KindInt64
	case int32:
		return KindInt32
	case int16:
		return KindInt16
	case int8:
		return KindInt8
	case int:
		return KindInt
	case uint64:
		return KindUint64
	case uint32:
		return KindUint32
	case uint16:
		return KindUint16
	case uint8:
		return KindUint8
	case uint:
		return KindUint
	case float64:
		return KindFloat64
	case float32:
		return KindFloat32
	case time.Time:
		return KindTime
	case time.Duration:
		return KindDuration
	case time.Weekday:
		return KindWeekday
	case time.Month:
		return KindMonth
	case complex64:
		return KindComplex64
	case complex128:
		return KindComplex128
	case net.IP:
		return KindIP
	case []byte:
		return KindBytes
	default:
		// 注意: KindSetString / KindSetInt 这两种类型由驱动层直接设置，此处不处理
		return KindSerializer // 其他类型，序列化存储
	}
}
